package block

import (
	"bytes"
	"crypto/sha256"
	"encoding/binary"
	"log"
	"time"
)

type Block struct {
	//版本号
	Version    uint64
	PrevHash   []byte
	MerkelRoot []byte
	TimeStamp  uint64
	Difficulty uint64 //难度
	Nonce      uint64 //随机数
	Hash       []byte
	Data       []byte
}

func (b *Block) SetHash() { //更新hash

	var blockInfo []byte
	blockInfo = append(blockInfo, Uint64ToByte(b.Version)...)
	blockInfo = append(blockInfo, b.PrevHash...)
	blockInfo = append(blockInfo, b.MerkelRoot...)
	blockInfo = append(blockInfo, Uint64ToByte(b.TimeStamp)...)
	blockInfo = append(blockInfo, Uint64ToByte(b.Difficulty)...)
	blockInfo = append(blockInfo, Uint64ToByte(b.Nonce)...)
	blockInfo = append(blockInfo, b.Data...)

	hash := sha256.Sum256(blockInfo)
	b.Hash = hash[:]

}

//create block
func NewBlock(data string, prevBlockHash []byte) *Block {
	block := Block{
		Version:    00,
		PrevHash:   prevBlockHash,
		MerkelRoot: []byte{},
		TimeStamp:  uint64(time.Now().Unix()),
		Difficulty: 0,
		Nonce:      0,
		Data:       []byte(data),
		Hash:       []byte{},
	}

	block.SetHash()

	return &block
}

//uin64转byte
func Uint64ToByte(num uint64) []byte {
	var buffer bytes.Buffer
	err := binary.Write(&buffer, binary.BigEndian, num)
	if err != nil {
		log.Panic(err)
	}

	return buffer.Bytes()
}
